You are getting duplicates because your filter is not evaluating the way you think it is.
The local-name() function returns the local name of the first node in the nodeset.
The only time your predicate filter would work is if the element happened to have the same name as the first preceding element.
I don't think you will be able to accomplish what you want with a pure XPATH 1.0 soultion. You could do it in XPATH 2.0, but that would not work with Firefox.
In XSLT you can use the meunchien method to accomplish what you want.
Below is an example. You didn't provide any sample XML, so I kept it very generic(e.g. //* matches for all elements in the doc):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="xml"/>
<xsl:key name="names" match="//*" use="local-name(.)"/>
<xsl:template match="/">
<xsl:for-each select="//*[generate-id(.) = generate-id(key('names', local-name(.)))]">
<!--Do something with the unique list of elements-->
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>